package cardsbody
{
	import Classes.CLoader;
	import Classes.pi_events;
	
	import UIFree.ObjectEvent;
	import UIFree.uif_component;
	
	import UIUtils.uif_util;
	
	import editor.pi_maskInfo;
	import editor.pj_extendServices;
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.BlendMode;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.filters.BlurFilter;
	import flash.geom.ColorTransform;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;

	public class pi_multicard extends pi_pngcard {
		private var _photos: Array;
		private var _curPhoto: int;
		private var _helper: Object;
		private static var HELPERNAME: String = 'helperMulti';
		private static const MULTYCARDPREFIX: String = 'pmc';
		
		public function pi_multicard(parent:uif_component, ax:int=0, ay:int=0, awidth:int=0, aheight:int=0, styleName:String='') {
			super(parent, ax, ay, awidth, aheight, styleName);
			_photos = new Array();
			_curPhoto = -1;
			_photoLayer.removeChild(_photoBitmap);
			if (editing) addEvent(MouseEvent.MOUSE_DOWN, doDown);
		}
		
		public function get curPhoto(): int {
			return _curPhoto;
		}
		
		public function get photos(): Array {
			return _photos;
		}
		
		override protected function doStorePhoto(): void {
			pj.dispatchEvent(new ObjectEvent(pi_events.STORE, MULTYCARDPREFIX + _curPhoto));
		}
		
		override protected function doRestorePhoto(): void {
			pj.dispatchEvent(new ObjectEvent(pi_events.RESTORE, MULTYCARDPREFIX + _curPhoto));
		}
		
		public function set curPhoto(a_set: int): void {
			if ((_curPhoto != a_set) && photoModified) {
				if (_curPhoto > -1)
					pj.dispatchEvent(new ObjectEvent(pi_events.STORE, MULTYCARDPREFIX + _curPhoto));
				
				_curPhoto = a_set;
				if (_curPhoto > -1) {
					maskInfo.pos = _photos[_curPhoto].rect;
					if (!_photos[_curPhoto].loader) {
						resetPhoto(_photo);
						app.dispatchEvent(new ObjectEvent(pi_events.SETPHOTORECT, new Point(maskInfo.pos.width, maskInfo.pos.height)));
					} else {
						pj.dispatchEvent(new ObjectEvent(pi_events.RESTORE, MULTYCARDPREFIX + _curPhoto));
/*						var mat: Matrix = _photos[_curPhoto].rmat;
						var rsize: Point = _photos[_curPhoto].rsize;
						function doLoadPhoto(e: Event): void {
							app.dispatchEvent(new ObjectEvent(pi_events.SETPHOTORECT, new Point(maskInfo.pos.width, maskInfo.pos.height)));
							pj.editor.photoBlock.rect.transform.matrix = mat;
							pj.editor.photoBlock.rect.applySize(rsize);
							storeEditRect();
						}
						oneEvent(Event.COMPLETE, doLoadPhoto, pj.editor.photoBlock.source.contentLoaderInfo);
						_photos[_curPhoto].loader.duplicate(pj.photo);*/
					}
					//refresh();
				}
				dispatchEvent(new ObjectEvent(pi_events.SETCURPHOTO, _curPhoto, true));
			}
		}
		
		protected function doDown(e: MouseEvent): void {
			if (photoModified) {
				var mPos	: Point = new Point(bitmap.mouseX, bitmap.mouseY);
				var mat		: Matrix = new Matrix();
				var scale	: Number = bitmap.width / contentSize.x;
				var np		: Point = new Point(0, 0);
				var hitIndex: int = -1;
	/*			mat.translate(bitmap.x, bitmap.y);
				mat.scale(scale, scale);
				mPos = mat.transformPoint(mPos);*/
				for (var i:int=0; i<_photos.length; i++) {
					var rect	: Rectangle = _photos[i].rect;
					rect = uif_util.scaleRect(rect, scale);
					if (rect.containsPoint(mPos)) {
						if (_photos[i].hasOwnProperty('mask')) {
							var lp: Point = new Point(mPos.x / scale - rect.x,
														mPos.y / scale - rect.y);
							if (!_photos[i].mask.bitmapData.hitTest(np, 0xFF, lp)) hitIndex = i;
						} else hitIndex = i;
					}
				}
				if (hitIndex > -1) curPhoto = hitIndex;
			}
		}
		
		override protected function doMaskPaint(bmdMask: BitmapData): void {
			super.doMaskPaint(bmdMask);
			updatePhotos(bmdMask);
		}
		
		override protected function getPackInfo(a_photoMatrix: Matrix, photoURL: String=''): String {
			var result: String = '';
			if (_maskInfo) {
				var mats	: String = '';
				var photos	: String = '';
				_photos.forEach(function(item: Object, index: int, arr: Array): void {
					var mat: Matrix = item.matrix;
					mats += (mats?'|':'') + (mat.a + ',' + mat.b + ',' + mat.c + ',' + mat.d + ',' + mat.tx + ',' + mat.ty);
					photos += (photos?'|':'') + (item.loader?item.loader.sourceUrl.replace('http://', ''):'');
				});
				result = _maskInfo.id + '~' + mats + '~' + photos;
				result += packExtend();
			}
			if (_effect) {
				if (_effect['packInfo']) result += '~' + _effect.packInfo();
				else result += '~' + effectID;
			} 
			return result;
		}
		
		override public function createFromSend(sendProc: Function): void {
			if (_photos.some(function(item: Object, index: int, arr: Array): Boolean {
				return (item.loader) && (item.loader.isDynamic);
			})) {
				pj.alert(pi_data.ERROR, pi_data.SENDMULTICARDDYNAMIC);
			} else sendProc(packInfo());
		}
		
		protected function photoBitmapCreate(a_photo: CLoader, photoIndex: int): void {
			if (_photos[photoIndex].bitmap.bitmapData) _photos[photoIndex].bitmap.bitmapData.dispose();
			_photos[photoIndex].bitmap.bitmapData = new BitmapData(a_photo.contentLoaderInfo.width, a_photo.contentLoaderInfo.height);
			_photos[photoIndex].bitmap.bitmapData.draw(a_photo);
			_photos[photoIndex].bitmap.smoothing = true;
			_photos[photoIndex].loader	= a_photo.duplicate();
		}
		
		protected function resetCurPhoto(a_photo: CLoader): void {
			if (_curPhoto > -1) {
				if (!_photos[_curPhoto].loader || 
					(_photos[_curPhoto].loader.sourceUrl != a_photo.sourceUrl)) {
					photoBitmapCreate(a_photo, _curPhoto);
					_photos[_curPhoto].ct = _colorsExt;
				}
			}
		}
		
		public function applyCurPhotoMatrix(matrix: Matrix): void {
			if (_curPhoto > -1) {
				_photos[_curPhoto].matrix = matrix;
			}			
		}
		
		override protected function resetPhoto(a_photo: CLoader): void {
			resetCurPhoto(a_photo);
			super.resetPhoto(a_photo);
		}
		
/*
		protected function storeEditRect(): void {
			_photos[_curPhoto].rmat = pj.editor.photoBlock.rect.transform.matrix;
			_photos[_curPhoto].rsize = pj.editor.photoBlock.rect.RSize;
		}
*/
		
		override public function applyPhotoMatrix(matrix: Matrix): void {
			if (photoModified) {
				applyCurPhotoMatrix(matrix);
				super.applyPhotoMatrix(matrix);
/*				if (editing && (_curPhoto > -1)) { // Запоминаем матрицу выделения
					pj.editor.photoBlock.dispatchEvent(new ObjectEvent(pi_events.STORE, MULTYCARDPREFIX + _curPhoto));
//					storeEditRect();
				}*/
			}
		}
		
		public function setCurColorExt(a_newColors: ColorTransform): void {
			if (_curPhoto > -1) {
				_photos[_curPhoto].ct = a_newColors;
			}			
		}
		
		override protected function setColorExt(a_newColors: ColorTransform): void {
			setCurColorExt(a_newColors);
			super.setColorExt(a_newColors);
		}
		
		override protected function paintoPhoto(a_bitmap: Bitmap, scale : Number): void {
			var matrix	: Matrix;
			if (_photoBitmap.bitmapData) {
				
				for (var i:int=0; i<_photos.length; i++) {
					var ct: ColorTransform = new ColorTransform();
					ct.concat(_maskInfo.colors);
					ct.concat(_photos[i].ct);
					
//					var cbmp: Bitmap = _photos[i].bitmap;
					var mat: Matrix = _photos[i].matrix.clone();
					var smat: Matrix = new Matrix();
					smat.scale(scale, scale);
					mat.concat(smat);
					
					var rect: Rectangle = _photos[i].rect.clone();
					var srect: Rectangle = new Rectangle();
					srect.topLeft 		= smat.transformPoint(rect.topLeft);
					srect.bottomRight	= smat.transformPoint(rect.bottomRight);
					
					if (_photos[i].hasOwnProperty('mask')) {
						var tmp: Bitmap = new Bitmap(new BitmapData(srect.width, srect.height));
						tmp.bitmapData.draw(_photos[i].bitmap, mat, null, null, null, true);
						tmp.bitmapData.draw(_photos[i].mask, smat, null, BlendMode.ERASE, null, false);
						
						mat = new Matrix();
						mat.translate(srect.x, srect.y);
						a_bitmap.bitmapData.draw(tmp, mat, ct, null, srect, false);
						
						tmp.bitmapData.dispose();
					} else {
						mat.translate(srect.x, srect.y);
						a_bitmap.bitmapData.draw(_photos[i].bitmap, mat, ct, null, srect, true);
					}
				}
				
/*				var cbmp: Bitmap = _photos[_curPhoto].bitmap;
				matrix = _photoMatrix.clone();
				cbmp.bitmapData.draw(_photoBitmap, matrix, ct, null, null, true);*/
				
/*				var b_matrix: Matrix = new Matrix();
				b_matrix.translate(_maskInfo.pos.x, _maskInfo.pos.y);
				b_matrix.scale(scale, scale);
				a_bitmap.bitmapData.draw(_photoTop, b_matrix, null, null, null, true);*/
			}			
		}
		
		protected function updatePhotos(bmdMask: BitmapData): void {
//			tmplColors.alphaMultiplier = 0.3;
			var i:int;
			var lrect: Rectangle;
			var tmp: BitmapData = bmdMask.clone();
			var mbright: Number = maskInfo.hasOwnProperty('mbright')?maskInfo.mbright:2;
			var ctc: ColorTransform = new ColorTransform(2, 2, 2, 1, -200 * mbright, -200 * mbright, -200 * mbright);
//			var ctc: ColorTransform = new ColorTransform(2, 2, 2, 1, -400, -400, -400);
			var defBlur: Number = tmp.rect.bottomRight.length / 100;
			var blur: Number = maskInfo.hasOwnProperty('mblur')?maskInfo.mblur:defBlur;
			var np	: Point 	= new Point(0, 0);
			
			if (blur) tmp.applyFilter(tmp, tmp.rect, new Point(0, 0), new BlurFilter(blur, blur, 3));
			tmp.colorTransform(tmp.rect, ctc);
			for (i=0; i<maskInfo.spots.length; i++) {
				var sp2: Array = maskInfo.spots[i];			
				if (sp2.length == 2) {
					var color: uint = 0xFFFF0000 | i;
					tmp.floodFill(sp2[0], sp2[1], color);
					lrect = tmp.getColorBoundsRect(0xFFFFFFFF, color, true);
					lrect.inflate(lrect.width / 40, lrect.height / 40);
					if (maskInfo.ismask) {
						var sh: Bitmap = new Bitmap(new BitmapData(lrect.width, lrect.height, true, 0xFFFFFFFF));
						sh.bitmapData.threshold(tmp, lrect, np, '==', color, 0, 0xFFFFFFFF, false);
						sh.bitmapData.applyFilter(sh.bitmapData, sh.bitmapData.rect, new Point(0, 0), new BlurFilter(defBlur, defBlur, 3));
						_photos[i].mask = sh;
					}
				} else lrect = new Rectangle(sp2[0], sp2[1], sp2[2] - sp2[0], sp2[3] - sp2[1]);
				
/*
				var bmask: Bitmap = new Bitmap(new BitmapData(lrect.width, lrect.height));
				var mat: Matrix = new Matrix();
				mat.translate(-lrect.x, -lrect.y);
				bmask.bitmapData.draw(bmdMask, mat, ctc);
				_photos[i].mask = bmask;
*/				
				
				_photos[i].rect = lrect;
			}
			
/*			if (_maskInfo.photoMatrix) {
				var mats: Array = _maskInfo.matrix.split('|');
				for (i=0; i<mats.length; i++) {
					var matA: Array = mats[i].split(',');
					_photos[i].matrix = new Matrix(matA[0], matA[1], matA[2], matA[3], matA[4], matA[5]);		
				} 
			}*/
			
			tmp.dispose();

/*			var mat: Matrix = new Matrix();
			var rect: Rectangle = uif_util.EnterHere(getInner(), new Point(tmp.width, tmp.height));
			var bm: Bitmap = new Bitmap(tmp);
			bm.alpha = 0.5;
			bm.width = rect.width;
			bm.height = rect.height;
			bm.x = rect.x;
			bm.y = rect.y;
			addChild(bm);*/
		}
		
		override protected function setPhotoMatrix(mat: Object): void {
			var mats: Array = mat.split('|');
			for (var i:int=0; i<mats.length; i++) {
				var matA: Array = mats[i].split(',');
				_photos[i].matrix = new Matrix(matA[0], matA[1], matA[2], matA[3], matA[4], matA[5]);		
			} 
		}
		
		override public function setMaskInfo(a_maskInfo: pi_maskInfo): void {
			if (editing) {
				_helper = pj_extendServices.loaded()[HELPERNAME];
				if (!_helper) pj_extendServices.loadService(HELPERNAME, function(e: Event): void {
					_helper = e.target.content;
					_helper.setCard(This);
				}) else _helper.setCard(This);
			}
			
			_maskInfo = a_maskInfo;
			createPhotos();
			super.setMaskInfo(a_maskInfo);
		}
		
		override protected function resetFromPhoto(): void {
			var phs: Array = _maskInfo.photo.split('|');
			var lcount: int = 0;
			function doComplete(e: Event): void {
				lcount--;
				if (lcount == 0) {
					for (var i:int = 0; i<phs.length; i++)
						if (phs[i]) {
							photoBitmapCreate(_photos[i].loader, i);
							if (!_photo.loaded) _photos[i].loader.duplicate(_photo);
						}
					resetFromMask();
				}
			}
			for (var i:int = 0; i<phs.length; i++) {
				if (phs[i]) {
					lcount++;
					_photos[i].loader = new CLoader(null, 'http://' + phs[i], doComplete);
				}
			}
		} 
		
		override protected function doLoadMask(e: Event): void {
			super.doLoadMask(e);
			if (editing) curPhoto = 0;
		}
		
		protected function createPhotos(): void {
			disposePhotos();
			for (var i:int=0; i<maskInfo.spots.length; i++) {
				var sbmp: Bitmap = new Bitmap();
				_photos.push({bitmap: sbmp, rect: null, loader: null, matrix: new Matrix(), ct: new ColorTransform()});
			}
		}
		
		protected function disposePhotos(): void {
			for (var i:int=0; i<_photos.length; i++) {
				if (_photos[i].bitmap.bitmapData) _photos[i].bitmap.bitmapData.dispose();
				if (_photos[i].loader) _photos[i].loader.unload();
				if (_photos[i].mask) _photos[i].mask.bitmapData.dispose();
				pj.dispatchEvent(new ObjectEvent(pi_events.DELSTORE, MULTYCARDPREFIX + i));
			}
			_photos.splice(0, _photos.length);
			curPhoto = -1;
		}
		
		override public function dispose(): void {
			disposePhotos();
			super.dispose();
		}
	}
}